package com.greateffect.littlebud.lib.utils;

import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;

import com.greateffect.littlebud.lib.listener.OnCommonListener;
import com.greateffect.littlebud.lib.utilcode.ToastUtils;
import com.zcs.autolayout.config.AutoLayoutConfig;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Locale;
import java.util.UUID;

/**
 * Created by ZengCS on 2018/12/21.
 * E-mail:zengcs@vip.qq.com
 * Add:成都市天府软件园E3
 */

public class BitmapUtils {
    /**
     * Constants
     */
    private static final String TAG = "BitmapUtil";
    private static final String CONTENT = "content";
    private static final String FILE = "file";
    public static File baseDir =
            new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                    .concat(File.separator)
                    .concat("sxw")
                    .concat(File.separator)
                    .concat("_temp")
                    .concat(File.separator)
                    .concat("pic")
                    .concat(File.separator));

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // 源图片的高度和宽度
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            // 计算出实际宽高和目标宽高的比率
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            // 选择宽和高中最小的比率作为inSampleSize的值，这样可以保证最终图片的宽和高
            // 一定都会大于等于目标的宽和高。
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }

    /**
     * 压缩图片
     *
     * @param filePath
     * @return
     */
    public static Bitmap compressFile(Context context, String filePath) {
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, opts);
        float scale_h = (float) opts.outHeight / (float) IScreenUtils.getScreenHeight(context);
        float scale_w = (float) opts.outWidth / (float) IScreenUtils.getScreenWidth(context);
        float scale = scale_h > scale_w ? scale_w : scale_h;
        if (scale <= 1) {
            scale = 1f;
        } else if (scale <= 2) {
            scale = 2f;
        } else if (scale <= 4) {
            scale = 4f;
        } else if (scale <= 8) {
            scale = 8f;
        } else {
            scale = 16f;
        }
        opts.inSampleSize = (int) scale;
        opts.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, opts);
    }

    /**
     * 压缩图片
     *
     * @param filePath
     * @return
     */
    public static Bitmap compressFile(Context context, String filePath, float width, float height) {
        JLogUtil.d(TAG, "compressFile() called with: " + "context = [" + context + "], filePath = [" + filePath + "], width = [" + width + "], height = [" + height + "]");
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, opts);
        float scale_h = (float) opts.outHeight / height;
        float scale_w = (float) opts.outWidth / width;
        JLogUtil.d(TAG, "compressFile: scale_h = " + scale_h);
        JLogUtil.d(TAG, "compressFile: scale_w = " + scale_w);
        float scale = scale_h > scale_w ? scale_w : scale_h;
        if (scale <= 1) {
            scale = 1f;
        } else if (scale <= 2) {
            scale = 2f;
        } else if (scale <= 4) {
            scale = 4f;
        } else if (scale <= 8) {
            scale = 8f;
        } else {
            scale = 16f;
        }
        JLogUtil.d(TAG, "compressFile: scale = " + scale);
        opts.inSampleSize = (int) scale;
        opts.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, opts);
    }

    /**
     * 获取文件的路径
     */
    public static String getFilePath(Context context, Uri uri) {
        String filePath = null;
        if (CONTENT.equalsIgnoreCase(uri.getScheme())) {
            Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.Media.DATA}, null, null, null);
            if (null == cursor) {
                return null;
            }
            try {
                if (cursor.moveToNext()) {
                    filePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
                }
            } finally {
                cursor.close();
            }
        }

        // 从文件中选择
        if (FILE.equalsIgnoreCase(uri.getScheme())) {
            filePath = uri.getPath();
        }
        return filePath;
    }

    /**
     * 根据指定比例缩放图片
     *
     * @param fileDescriptor
     * @param reqWidth
     * @return
     * @author blue
     */
    public static Bitmap decodeSampledBitmap(FileDescriptor fileDescriptor, int reqWidth, int reqHeight) {
        JLogUtil.d(TAG, "decodeSampledBitmap() called with: " + "fileDescriptor = [" + fileDescriptor + "], reqWidth = [" + reqWidth + "], reqHeight = [" + reqHeight + "]");
        // 第一次解析将inJustDecodeBounds设置为true，来获取图片大小
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
        // 调用上面定义的方法计算inSampleSize值
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // 使用获取到的inSampleSize值再次解析图片
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
    }

    public static Bitmap decodeSampledBitmap(InputStream inputStream, int reqWidth, int reqHeight) throws FileNotFoundException {
        // 第一次解析将inJustDecodeBounds设置为true，来获取图片大小
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(inputStream, null, options);
        // 调用上面定义的方法计算inSampleSize值
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // 使用获取到的inSampleSize值再次解析图片
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeStream(inputStream, null, options);
    }

    public static Bitmap decodeSampledBitmap(Resources resources, int resId, int reqWidth, int reqHeight) throws FileNotFoundException {
        // 第一次解析将inJustDecodeBounds设置为true，来获取图片大小
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(resources, resId, options);
        // 调用上面定义的方法计算inSampleSize值
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // 使用获取到的inSampleSize值再次解析图片
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(resources, resId, options);
    }

    /**
     * 保存Bitmap到SDCard
     *
     * @param bitmap
     * @param filePath 图片保存路径
     */
    public static boolean saveBitmap(Bitmap bitmap, String filePath, int quality) {
        if (!baseDir.exists())
            baseDir.mkdirs();

        boolean success;
        File file = new File(filePath);
        if (file.exists()) {
            boolean delete = file.delete();
            if (delete) {
                JLogUtil.d("旧文件已删除");
            }
        }
        File dir = file.getParentFile();
        if (!dir.exists()) {
            boolean mkdirs = dir.mkdirs();
            if (!mkdirs) {
                return false;
            }
        }
        try {
            FileOutputStream out = new FileOutputStream(file);
            if (bitmap != null && !bitmap.isRecycled())
                bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out);
            out.flush();
            out.close();
            success = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            success = false;
        } catch (IOException e) {
            e.printStackTrace();
            success = false;
        }
        return success;
    }

    /**
     * 保存Bitmap到SDCard
     *
     * @param bitmap
     */
    public static boolean saveBitmap(Bitmap bitmap, String filePath, double avatarSize) {
        if (!baseDir.exists())
            baseDir.mkdirs();

        boolean success;
        bitmap = zoomImage(bitmap, avatarSize, avatarSize);
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        }
        try {
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.flush();
            out.close();
            success = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            success = false;
        } catch (IOException e) {
            e.printStackTrace();
            success = false;
        }
        return success;
    }


    /**
     * 将图片缩放到指定尺寸
     *
     * @param sourceBitmap 图片源
     * @param newWidth     新的宽度
     * @param newHeight    新的高度
     * @return
     */
    public static Bitmap zoomImage(Bitmap sourceBitmap, double newWidth, double newHeight) {
        // 获取这个图片的宽和高
        float width = sourceBitmap.getWidth();
        float height = sourceBitmap.getHeight();
        // 创建操作图片用的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, (int) width, (int) height, matrix, true);
        return bitmap;
    }

    /**
     * 清空临时图片
     */
    public static void clearTempPic() {
        int count = 0;
        if (baseDir.exists()) {
            File[] files = baseDir.listFiles();
            if (files != null && files.length > 0)
                for (File file : files) {
                    if (file.exists()) {
                        if (file.delete())
                            count++;
                    }
                }
        }
        JLogUtil.d("本次共删除临时图片" + count + "张");
    }

    public static boolean deleteFile(String filePath) {
        try {
            File file = new File(filePath);
            if (file.exists()) {
                return file.delete();
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static File saveAsUri(Context context, Uri uri) {
        Bitmap bitmapFromUri = getBitmapFromUri(context, uri);
        return saveAsBitmap(context,bitmapFromUri);
    }

    /**
     * 对指定的bitmap进行压缩
     * @param context
     * @param bmp
     * @return
     */
    public static File saveAsBitmap(Context context, Bitmap bmp){
        if (bmp == null || bmp.isRecycled())
            return null;
        String uuid = UUID.randomUUID().toString();
        // String fileName = baseDir.getAbsolutePath().concat(File.separator).concat(uuid).concat(".compress");
        String fileName = baseDir.getAbsolutePath().concat(File.separator).concat(uuid).concat(".jpg");// 直接以UUID命名,无需后缀
        // 压缩图片至最大200Kb
        File file = XtImageUtils.compressImage(new File(fileName), bmp, 200);
        if (file != null) {
            return file;
        }
        saveBitmap(bmp, fileName, 35);
        return new File(fileName);
    }

    public static Bitmap getBitmapFromUri(Context context, Uri uri) {
        try {
            // 读取uri所在的图片
            return MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
        } catch (Exception e) {
            Log.e("[Android]", e.getMessage());
            Log.e("[Android]", "目录为：" + uri);
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取网络视频资源的缩略图
     *
     * @param url
     * @return
     */
    public static void getNetVideoThumbnail(String url, int width, int height, OnCommonListener<Bitmap> listener){
        new Thread(new Runnable() {
            @Override
            public void run() {
                Bitmap bitmap = null;
                MediaMetadataRetriever retriever = new MediaMetadataRetriever();
                try {
                    //本地资源
//                  retriever.setDataSource(url);
                    //网络资源地址
                    retriever.setDataSource(url, new HashMap<String, String>());
                    bitmap = retriever.getFrameAtTime();
                    if(width > 0 && height > 0) {
                        bitmap = zoomImage(bitmap, width, height);
                    }
                }catch (IllegalArgumentException ex){
                    JLogUtil.e(String.format(Locale.CHINESE,"资源（%s）的缩略图获取失败",url));
                }catch (RuntimeException ex){
                    JLogUtil.e(String.format(Locale.CHINESE,"资源（%s）的缩略图获取失败",url));
                }finally {
                    retriever.release();
                    if (listener != null) {
                        listener.onDoNext(bitmap);
                    }
                }
            }
        }).start();
    }

    /**
     * 获取正在播放视频截图
     *
     * @param url
     * @return
     */
    public static void getNetVideoBitmap(String url, long playTime, OnCommonListener<Bitmap> listener){
        new Thread(new Runnable() {
            @Override
            public void run() {
                Bitmap bitmap = null;
                MediaMetadataRetriever retriever = new MediaMetadataRetriever();
                try {
                    //本地资源
//                  retriever.setDataSource(url);
                    //网络资源地址
                    retriever.setDataSource(url, new HashMap<String, String>());
                    bitmap = retriever.getFrameAtTime(playTime);
                }catch (IllegalArgumentException ex){
                    JLogUtil.e(String.format(Locale.CHINESE,"资源（%s）的截图获取失败",url));
                }catch (RuntimeException ex){
                    JLogUtil.e(String.format(Locale.CHINESE,"资源（%s）的截图获取失败",url));
                }finally {
                    retriever.release();
                    if (listener != null) {
                        listener.onDoNext(bitmap);
                    }
                }
            }
        }).start();
    }

    /**
     * 获取截屏信息（非使用权限截屏）
     * @param view
     * @return
     */
    public static Bitmap shotScreen(View view){
        if(view == null){
            return null;
        }
        //允许当前窗口保存缓存信息
         view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();

        //获取屏幕宽和高
        int width = view.getWidth();
        int height = view.getHeight();

        if(width == 0 || height == 0){
            width = AutoLayoutConfig.getInstance().getScreenWidth();
            height = AutoLayoutConfig.getInstance().getScreenHeight();
        }

        // 全屏不用考虑状态栏，有导航栏需要加上导航栏高度
        Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, 0, width, height);

        view.buildDrawingCache(false);
        //销毁缓存信息
        view.destroyDrawingCache();
        if (bitmap == null) {
            ToastUtils.showShort("获取屏幕失败，请重试。");
            return null;
        }
        return bitmap;
    }



}
